<?php

namespace app\server\im\controller;

use app\common\model\Auth;
use app\common\model\Config;
use app\common\model\Db;
use GuzzleHttp\Client;
use JMessage\IM\Message;
use JMessage\JMessage;
use variant\library\vari\Log;

class Http
{

    private $_worker;

    private $_client;

    private $_httpClient;

    /**
     * im host
     *
     * @var
     */
    private $_imHost;

    /**
     * im 端口
     *
     * @var
     */
    private $_imPort;


    /**
     * Http constructor.
     */
    public function __construct()
    {

        $this->_imHost = Config::get('im_server.host', 'im');
        $this->_imPort = Config::get('im_server.port', 'im');

        $key = Config::get('app_key', 'im');
        $secret = Config::get('master_secret', 'im');
        $this->_client = new JMessage($key, $secret);
        $this->_httpClient = new Client();
        /**
         * 实例邮件服务
         */
        $this->_worker = new \Swoole\Http\Server($this->_imHost, $this->_imPort);

        /**
         * 设置
         */
        $this->_worker->set([
            'worker_num' => 4,
            'task_worker_num' => 4,
            'daemonize' => 1
        ]);
        $this->_worker->on('Request', [$this, 'onRequest']);
        $this->_worker->on('Task', [$this, 'onTask']);
        $this->_worker->on('Finish', [$this, 'onFinish']);
        $this->_worker->start();
    }

    /**
     * 请求回调
     *
     * @param $request
     * @param $response
     * @return mixed
     */
    public function onRequest($request, $response)
    {
        if ($request->server['path_info'] == '/favicon.ico' || $request->server['request_uri'] == '/favicon.ico') {
            $response->status(404);
            return $response->end();
        }

        $post = $request->rawContent();
        $post = json_decode($post, true);
        $post['port'] = $request->server['server_port'];
        $token = $request->header['authorization'] ?? null;
        $post['token'] = $token;
        Log::instance()->info(var_export($request, true));
        /**
         * 验证请求者
         */
        if (!(new Auth($post))->verify()) {
            $response->status(401);
            return $response->end("unauthorized");
        }

        if (!$post['to_user'] || !is_array($post['to_user'])) {
            return $response->end('to_user must be an array');
        }
        if (!$post['buttons'] || !is_array($post['buttons'])) {
            return $response->end('buttons must be an array');
        }

        $buttons = [];

        foreach ($post['buttons'] as $k => $v) {
            if (empty($v['title']) || empty($v['url'])) {
                return $response->end('IM_PUSH_MESSAGE_FAILED');
            }
            $buttons[$k] = [];
            $buttons[$k]['title'] = htmlspecialchars($v['title'], ENT_QUOTES);
            $buttons[$k]['url'] = htmlspecialchars($v['url'], ENT_QUOTES);
        }

        /**
         * 自定义通知
         */
        $messageBody = [
            'msg_type' => 'CUSTOM_NOTICE',
            'msg_content' => [
                //缩略图
                'thumb' => $post['thumb'] ?? null,
                //原图
                'original_img' => $post['original_img'] ?? null,
                //标题
                'title' => htmlspecialchars($post['title'] ?? null, ENT_QUOTES),
                //描述
                'description' => htmlspecialchars($post['description'] ?? null, ENT_QUOTES),
                //时间
                'createTime' => intval($post['createTime'] ?? null),
                //详情地址 默认按钮动作
                'url' => htmlspecialchars($post['url'] ?? null, ENT_QUOTES),
                'buttons' => $buttons
            ]
        ];

        /**
         * 推送客户端
         */
        $info = [
            'type' => 'message',
            'to_user' => $post['to_user'],
            'body' => [
                'title' => htmlspecialchars($post['title'] ?? null, ENT_QUOTES),
                'original_img' => $post['original_img'] ?? null,
                'thumb' => $post['thumb'] ?? null,
                'description' => htmlspecialchars($post['description'] ?? null, ENT_QUOTES),
                'createTime' => intval($post['createTime'] ?? null),
                'url' => htmlspecialchars($post['url'] ?? null, ENT_QUOTES),
            ]
        ];
        $pushDevice = [
            'body' => json_encode($info)
        ];

        $httpRes = $this->_httpClient->post(Config::get('to_device_url', 'im'), $pushDevice);
        $httpRes = json_decode(strval($httpRes->getBody()), true);
        if ($httpRes['status'] != 0) {
            Log::instance()->error(var_export($httpRes, true));
        }

        //目标用户
        foreach ($post['to_user'] as $v) {
            $target = 'user_' . $v;
            $messageBody['target'] = $target;
            $this->_worker->task($messageBody);
        }
        return $response->end('ok');
    }

    /**
     * 更新发送消息状态
     *
     * @param $target
     * @param $content
     * @return bool
     */
    private function sendSingleMessage($target, $content)
    {
        $message = new Message($this->_client);
        $from = [
            'type' => 'admin',
            'id' => '10001'

        ];
        $target = [
            'type' => 'single',
            'id' => $target
        ];
        $msg = [
            'text' => $content['msg_content']['description'],
            'extras' => $content
        ];

        $r = $message->sendText("1", $from, $target, $msg);

        if (is_string($r)) {
            //记录错误记录
            Log::instance()->error('im 消息发送超时 ' . $r);
            return false;
        }
        if ($r['http_code'] == 201) {
            return true;
        }
        //记录错误记录
        Log::instance()->error('im 消息发送失败 ' . var_export($r, true));
        return false;
    }

    /**
     * @param $ser
     * @param $task_id
     * @param $from_id
     * @param $data
     */
    public function onTask($ser, $task_id, $from_id, $data)
    {

        try {
            $target = $data['target'];
            unset($data['target']);
            $r = $this->sendSingleMessage($target, $data);
            if ($r) {
                $ser->finish($data);
            }
        } catch (\Exception $exception) {
            Log::instance()->error($exception->getMessage());
        }

    }

    /**
     * 任务完成
     *
     * @param $ser
     * @param $task_id
     * @param $data
     */
    public function onFinish($ser, $task_id, $data)
    {
    }


}